/**
 * 
 */
package com.effectiv.gooruda.rest.api.service;

import java.util.List;

import lombok.extern.slf4j.Slf4j;

import org.hornetq.api.jms.management.JMSQueueControl;
import org.hornetq.api.jms.management.JMSServerControl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.PageRequest;
import org.springframework.stereotype.Component;

import com.effectiv.gooruda.domain.CloudQueue;
import com.effectiv.gooruda.repository.CloudQueueRepository;
import com.effectiv.gooruda.rest.api.exception.QueueOperationException;
import com.effectiv.gooruda.rest.api.operation.QueueOperations;
import com.effectiv.gooruda.security.rest.RESTSecurityUtil;

/**
 * @author Dhrubo
 * 
 */
@Component
@Slf4j
public class QueueServiceImpl implements QueueOperations {
	
	@Autowired
	private HornetQManagementHelper managementHelper;

	@Autowired
	private CloudQueueRepository repository;

	private final String QNAME_TEMPLATE = "q.";

	protected String getDestinationName(String queueName) {
		return QNAME_TEMPLATE + RESTSecurityUtil.getAppId() + "." + queueName;
	}

	// UC:001
	@Override
	public List<CloudQueue> findAll(int pageNo, int pageSize) {

		if (pageNo == -1) {
			pageNo = 0;
			pageSize = 10;
		}

		if (pageSize > 20) {
			pageSize = 20;
		}

		PageRequest request = new PageRequest(pageNo, pageSize);

		List<CloudQueue> qs = repository.findByApplication(request,
				RESTSecurityUtil.getApplication());

		return qs;
	}

	// UC : 002
	@Override
	public CloudQueue findByName(String queueName) {
		CloudQueue q = repository.findByCname(getDestinationName(queueName));

		if (q != null) {
			JMSQueueControl qControl = managementHelper.getJMSQueueControl(q
					.getCname());
			
			log.info("qControl == {}", qControl);
			
			try {
				q.setSize(qControl.getMessageCount());
			} catch (Exception e) {
				throw new QueueOperationException(
						"Error getting queue message count", e);
			}
		} else {
			throw new QueueOperationException("Queue with name - " + queueName
					+ " not attached to application ");
		}

		return q;
	}

	// UC : 003
	@Override
	public void delete(String queueName) {
		try {
			JMSServerControl serverControl = managementHelper
					.getJMSServerControl();
			serverControl.destroyQueue(getDestinationName(queueName));

			CloudQueue q = repository
					.findByCname(getDestinationName(queueName));
			repository.delete(q);

		} catch (Exception e) {
			throw new QueueOperationException(
					"Error deleting queue with name - " + queueName, e);
		}

	}

	@Override
	// UC : 004
	public void create(String queueName) {

		log.info("Creating queue with name - {} for app = {}", queueName,
				RESTSecurityUtil.getApplication().getName());

		try {

			JMSServerControl serverControl = managementHelper
					.getJMSServerControl();
			serverControl.createQueue(getDestinationName(queueName));

			CloudQueue q = new CloudQueue();
			q.setCname(getDestinationName(queueName));
			q.setName(queueName);
			q.setApplication(RESTSecurityUtil.getApplication());

			repository.save(q);

		} catch (Exception e) {
			
			log.error("Error", e);
			
			throw new QueueOperationException(
					"Error creating queue with name - " + queueName, e);
		}

	}

	@Override
	// UC : 005
	public void purge(String queueName) {
		CloudQueue q = repository.findByCname(getDestinationName(queueName));

		if (q != null) {

			JMSQueueControl qControl = managementHelper.getJMSQueueControl(q
					.getCname());
			try {
				int count = qControl.removeMessages(null);
			} catch (Exception e) {
				throw new QueueOperationException(
						"Error purging queue with name - " + queueName
								+ " not attached to application ");
			}
		} else {
			throw new QueueOperationException("Queue with name - " + queueName
					+ " not attached to application ");
		}
	}

}
